package br.unicamp.ic.inf312.arena.persistencia.dao.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import br.unicamp.ic.inf312.arena.modelo.logistico.Assento;
import br.unicamp.ic.inf312.arena.modelo.logistico.Evento;
import br.unicamp.ic.inf312.arena.modelo.pessoa.Espectador;
import br.unicamp.ic.inf312.arena.modelo.pessoa.Estudante;
import br.unicamp.ic.inf312.arena.modelo.pessoa.Profissional;
import br.unicamp.ic.inf312.arena.modelo.vendas.Bilhete;
import br.unicamp.ic.inf312.arena.modelo.vendas.BilheteInteiro;
import br.unicamp.ic.inf312.arena.modelo.vendas.BilheteMeiaEntrada;
import br.unicamp.ic.inf312.arena.modelo.vendas.Compra;
import br.unicamp.ic.inf312.arena.modelo.vendas.Estorno;
import br.unicamp.ic.inf312.arena.persistencia.dao.IBilheteDAO;
import br.unicamp.ic.inf312.framework.persistencia.SQLUtil;

public class BilheteDAOMySQL implements IBilheteDAO {

	/**
	 * 
	 */
	public int insert(Bilhete bilhete) throws Exception {
		int result = 0;
		if (bilhete != null) {
			StringBuffer stbQuery = new StringBuffer();
			stbQuery.append(" INSERT INTO ");
			stbQuery.append(SQLUtil.getDbSchema() + "." + IBilheteDAO.TABELA_BD
					+ " (");
			stbQuery.append(IBilheteDAO.COLUMN_CODIGO_PK 		+ ", ");
			stbQuery.append(IBilheteDAO.COLUMN_TIPO 			+ ", ");
			stbQuery.append(IBilheteDAO.COLUMN_ESTADO 			+ ", ");
			stbQuery.append(IBilheteDAO.COLUMN_NUMERO_PROTOCOLO + ", ");
			stbQuery.append(IBilheteDAO.COLUMN_DOCUMENTO 		+ ", ");
			stbQuery.append(IBilheteDAO.COLUMN_CODIGO_EVENTO 	+ ", ");
			stbQuery.append(IBilheteDAO.COLUMN_CODIGO_ASSENTO 	+ ", ");
			stbQuery.append(IBilheteDAO.COLUMN_NUMERO_ESTORNO 	+ ") ");//TODO:?
			stbQuery.append(" VALUES (?, ?, ?, ?, ?, ?, ?, ?) ");
			//
			Object[] params = new Object[8];
			params[0] = bilhete.getNumero();
			params[1] = bilhete.getTipo();
			params[2] = bilhete.getEstado();
			params[3] = bilhete.getCompra().getNumProtocolo();
			params[4] = bilhete.getEspectador().getDocumento();
			params[5] = bilhete.getEvento().getCodEvento();
			//TODO: IMPORTANTE - distinguir tipos de sala / assento conforme tipo do espetaculo
/*
			params[6] = bilhete.getEvento().getSala()
					.getProximoAssentoDisponivel().getCodigo();
*/
			params[6] = bilhete.getAssento().getNumero();

			if ( bilhete.getEstorno() != null ) {
				params[7] = bilhete.getEstorno().getNumero();
			} else {
				params[7] = 0;
			}

			//
			result = SQLUtil.update(stbQuery.toString(), params);
		}
		return result;
	}

	/**
	 * 
	 */
	public Bilhete obterBilhete(long numero) throws Exception {
		return null;
	}

	/**
	 * 
	 */
	public Collection<Bilhete> obterBilhetes(long numProtocolo)
			throws Exception {
		StringBuffer stbQuery = new StringBuffer();
		stbQuery.append("SELECT ");
		stbQuery.append("  b.numero, b.estado, b.tipo, b.documento, ");
		stbQuery.append("  b.numprotocolo, b.codevento, b.codassento, b.numeroEstorno ");
		stbQuery.append("FROM ");
		stbQuery.append("  bilhete b, compra c ");
		stbQuery.append("WHERE ");
		stbQuery.append("  b.numprotocolo   = ?              AND ");
		stbQuery.append("  b.numprotocolo   = c.numprotocolo ");

		Object[] params = new Object[1];
		params[0] = numProtocolo;
		//
		Collection<Bilhete> bilhetes = null;

		//selectRecordS
		ArrayList result = null;
		result = (ArrayList) SQLUtil.selectRecordS(stbQuery.toString(), params);
		if (result != null && result.size() > 0) {
			Bilhete bilhete = null;
			bilhetes = new ArrayList<Bilhete>();

			for (Iterator iter = result.iterator(); iter.hasNext();) {
				Object[] record = (Object[]) iter.next();
				//
				if (record != null && record.length > 0) {
					long numero 		= ((Long)    record[0]).longValue();
					int  estado 		= ((Integer) record[1]).intValue();
					int  tipo   		= ((Integer) record[2]).intValue();
					String strDocto 	= ((String)  record[3]);
					long numprotocolo 	= ((Long)    record[4]).longValue();
					long codevento 		= ((Long)    record[5]).longValue();
					int  codassento   	= ((Integer) record[6]).intValue();

					Estorno estorno = null;
					if (record[7] != null) { //coluna aceita nulo
						estorno = new Estorno();
						estorno.setNumero( ((Long) record[7]).longValue() );
					}

					Evento evento = new Evento();
					evento.setCodEvento(codevento); //TODO: carregar da base?

					Compra compra = new Compra();
					compra.setNumProtocolo(numprotocolo);

					Assento assento = new Assento();
					assento.setCodigo(codassento);

					if (tipo == Bilhete.TIPO_INTEIRO) {
						Espectador profissional = new Profissional(strDocto);
						bilhete = new BilheteInteiro(numero, estado,
								profissional, evento, compra, assento, estorno);

					} else if(tipo == Bilhete.TIPO_MEIA_ENTRADA) {
						Espectador estudante = new Estudante(strDocto);
						bilhete = new BilheteMeiaEntrada(numero, estado,
								estudante, evento, compra, assento, estorno);
					}
					
					//TODO: Alteracao para a ativ. 11
					// adiciona o bilhete a colecao
					bilhetes.add( bilhete );
				}
			}
		}
		return bilhetes;
	}
}